package restaurant;

import java.util.ArrayList;

import restaurant.iterators.AssignedTablesIterator;
import restaurant.iterators.EmptyTablesIterator;
import restaurant.iterators.Iterator;
import restaurant.iterators.OrderedTablesIterator;

/**
 * Represents the tables at the restaurant. The {@code Tables} class is a
 * collection of {@code Table} objects. In order to access a {@code Table}, the
 * program must go through the {@code Tables} class.
 * 
 * @author Odessa
 * @see Table
 */

public class Tables
{

	/** The list of all tables. */
	private ArrayList<Table> tables;

	/** The number of tables currently empty. */
	private int numEmpty = 0;

	/** The table number. */
	private int tableNumber = 1;



	/**
	 * Instantiates the tables.
	 */
	public Tables() {
		tables = new ArrayList<Table>();
	}



	/**
	 * Creates a new table. This table's capacity will be set to the default.
	 * The {@code tableNumber} is used so that each table created has a unique
	 * table number. After the table is created, it is added to the list of
	 * tables and the {@code tableNumber} gets incremented.
	 * 
	 * @return the newly created table.
	 */
	public Table newTable()
	{
		Table t = new Table(tableNumber);
		add(t);
		tableNumber++;

		return t;
	}



	/**
	 * Adds the {@code table} to the tables ArrayList. Takes a table and appends
	 * it to the end of the list.
	 * 
	 * @param table the table to be added to the list of tables.
	 */
	public void add(Table table)
	{
		tables.add(table);
	}



	/**
	 * Deletes a table. It first finds the table in the list of tables and then
	 * deletes it.
	 * 
	 * @param tableNo the table number of the table to be deleted.
	 */
	public void delete(int tableNo)
	{
		Table t = find(tableNo);
		tables.remove(t);
	}



	/**
	 * Finds a table. It looks at all the tables in the list of tables and
	 * returns the table with the specified table number.
	 * 
	 * @param tableNo the table number of the table to find.
	 * @return the table matching the table number entered.
	 */
	private Table find(int tableNo)
	{
		Table table = null;

		for (Table t : tables) {
			int id = t.getTableNo();

			if (id == tableNo) {
				table = t;
				break;
			}
		}

		return table;
	}



	/**
	 * Activates a table. It checks to determine if the pin entered by the
	 * customer matches the pin associated with their table.
	 * 
	 * @param tableNo the table number of the table to activate.
	 * @return {@code true} if the table was activated.
	 */
	public void activateTable(int tableNo)
	{
		Table t = find(tableNo);
		t.setActivated();
	}



	/**
	 * Sets a table as being assigned.
	 * 
	 * @param tableNo the table number of the table being assigned.
	 */
	public void assignTable(int tableNo)
	{
		Table t = find(tableNo);
		t.setAssigned();
	}



	/**
	 * Sets a table as having placed an order.
	 * 
	 * @param tableNo the table number of the table that has ordered.
	 */
	public void orderPlaced(int tableNo)
	{
		Table t = find(tableNo);
		t.setOrdered();
	}



	/**
	 * Sets a table as having their order delivered.
	 * 
	 * @param tableNo the table number of the table whose order was delivered.
	 */
	public void orderDelivered(int tableNo)
	{
		Table t = find(tableNo);
		t.setDelivered();
	}



	/**
	 * Gets the pin value for a table.
	 * 
	 * @param tableNo the table number whose pin is retrieved.
	 * @return the table pin
	 */
	public int getTablePin(int tableNo)
	{
		Table t = find(tableNo);

		return t.getPin();
	}



	/**
	 * Sets the pin value for a table.
	 * 
	 * @param tableNo the table number whose pin is being set.
	 * @param newPin the pin of the table.
	 */
	public void setTablePin(int tableNo, int newPin)
	{
		Table t = find(tableNo);
		t.setPin(newPin);
	}



	/**
	 * Resets a table.
	 * 
	 * @param tableNo the table number of the table being reset.
	 */
	public void resetTable(int tableNo)
	{
		Table t = find(tableNo);
		t.reset();
	}



	/**
	 * Gets the AssignedTablesIterator.
	 * 
	 * @return the iterator to view the assigned tables.
	 * @see AssignedTablesIterator
	 */
	public Iterator getAssignedTablesIterator()
	{
		return new AssignedTablesIterator(tables);
	}



	/**
	 * Gets the EmptyTablesIterator.
	 * 
	 * @return the iterator to view the empty tables.
	 * @see EmptyTablesIterator
	 */
	public Iterator getEmptyTablesIterator()
	{
		return new EmptyTablesIterator(tables);
	}



	/**
	 * Gets the OrderedTablesIterator.
	 * 
	 * @return the iterator to view the tables waiting on their orders.
	 * @see OrderedTablesIterator
	 */
	public Iterator getOrderedTablesIterator()
	{
		return new OrderedTablesIterator(tables);
	}



	/**
	 * Gets the number of empty tables.
	 * 
	 * @return the number of empty tables.
	 */
	public int getNumEmpty()
	{
		Iterator empty = getEmptyTablesIterator();

		while (empty.hasNext())
			numEmpty++;

		return numEmpty;
	}
}
